#pragma once

#include "nocopy.hpp"
#include "Log.hpp"
#include <cerrno>
#include <cstring>
#include <sys/epoll.h>

class Epoller : public nocopy
{
    static const int size = 128;

private:
    int _epollFd;
    int _timeout{3000};

public:
    Epoller()
    {
        _epollFd = epoll_create(size);
        if (_epollFd == -1)
            lg(Error, "epoll_create error: %s", strerror(errno));
        else
            lg(Info, "epoll_create success: %d", _epollFd);
    }

    int EpollerWait(struct epoll_event revents[], int num)
    {
        // int epoll_wait(int __epfd, epoll_event *__events, int __maxevents, int __timeout)
        int n = epoll_wait(_epollFd, revents, num, /*_timeout 0*/ -1);
        return n;
    }

    int EpllerUpdate(int oper, int sock, uint32_t event)
    {
        // int epoll_ctl(int __epfd, int __op, int __fd, epoll_event *)
        int n = 0;
        if (oper == EPOLL_CTL_DEL)
        {
            n = epoll_ctl(_epollFd, oper, sock, nullptr);
            if (n != 0)
                lg(Error, "epoll_ctl delete error!");
        }
        else // EPOLL_CTL_MOD || EPOLL_CTL_ADD
        {
            struct epoll_event ev;
            ev.events = event;
            ev.data.fd = sock; // 方便后期得知 是哪一个fd就绪了

            n = epoll_ctl(_epollFd, oper, sock, &ev);
            if (n != 0)
                lg(Error, "epoll_ctl error!");
        }
        return n;
    }

    ~Epoller()
    {
        if (_epollFd >= 0)
            close(_epollFd);
    }
};
